/* 
    1.promise是一个类 在执行这个类的时候 需要传递一个执行器 并且立即执行
    2.Promise 有三种状态 成功 fulfilled 失败 rejected 等待 pending
        pending-> fulfilled 
        pending-> rejected
        一旦状态改变就不可更改
    3.resolve reject 函数是用来改变状态的 
        resolve - fulfilled
        reject - rejected
    4.then方法内部做的事情是判断状态，状态成功就调用成功回调，状态失败 就调用失败的回调 then方法被定义在原型对象上
    5.then 成功回调有一个参数 表示成功之后的值 then失败回调 有一个参数表示失败后的原因
    6.promise 的then是可以多次调用的，在异步的时候 就需要把成功回调和失败回调 存储起来 等状态为成功/失败的时候再次执行
    7.then方法是可以被链是调用的 后台的then方法的回调函数 拿到的值是上一个then方法的 回调函数的返回值
    8.实现then 方法的链式调用 必须是then方法返回一个promise对象 这样才能实现then的链式调用
    9.then方法可以返回一个promise对象 或者普通值 如果是普通值就直接通过resolve传递。
        如果是promise对象查看返回状态成功状态调用resolve方法把  这个状态传递下去。如果是失败状态就调用reject方法，把这个状态传递下去
    10.then方法不能返回当前这个promise对象 会发生promise的循环调用
    11.为了程序的健壮性，我们还是有必要去捕获错误，处理错误， 异常要报错
    12.then方法参数 变为可选参数  判断then是否有参数，没有的时候then(value=> value)向下传递一直到有参数的then
    13.promise.all 允许我们按照异步代码调用的顺序得到异步代码执行的顺序
        接收数组，可以是promise对象 或普通值 
        返回是个promise对象 后面可以链接then 
        所有成功 promise.all才是成功 有一个失败就是失败
        同过promise.all 调用 all是个静态方法
    14.promise.resolve 是将给定的值转化为promise对象，也就是返回promise对象包裹给定值
        如果是普通值就用promise对象包裹并返回 
        是promise对象就原封不动的返回出来
    15.finally 无论promise执行的是成功还是失败都要执行一次，并且可以在后面then链式调用
    16.catch 处理当前这个promise为失败的情况
    17.promise.reject() 返回一个失败的结果 参数会原封不动的作为reject的失败缘由
    18.promise.race() 返回promise对象，参数数组，第一个完成的promise是成功它就是成功，是失败就是它就是失败
        参数空则不执行

*/
const MyPromise = require('./mypromise')
let promise = new MyPromise((resolve, reject)=> {
    setTimeout(()=> {
        resolve('成功---')
    },2000)
    // throw new Error('executor error')
    // resolve('成功')
    // reject('失败')
})

// 多次调用then
// promise.then(value => {
//     console.log(value)
// }, reason=> {
//     console.log(reason)
// })
// promise.then(value => {
//     console.log(value)
// }, reason=> {
//     console.log(reason)
// })

// then的链式调用
// function other() {
//     return new MyPromise((resolve, reject)=> {
//         resolve('other');
//     })
// }
// let p1 = promise.then(value => {
//     console.log(value)
//     return p1;
// }).then(value => {
//     console.log(value)
// },reason => {
//     console.log(reason.message)
// })
// promise.then(value => {
//     console.log(value)
//     return 'aaaa'
// }).then(value=> {
//     console.log(value)
// })

function p1 () {
    return new MyPromise(function(resolve, reject) {
        setTimeout(()=> {
            resolve('p1')
        },2000)
    })
}
function p2 () {
    return new MyPromise(function(resolve, reject) {
        resolve('p2')
    })
}
// p1().then(value=> {
//     console.log(value)
// },()=> {}) 

// MyPromise.all(['a','b',p1(),p2(),'c']).then(result => {
//     console.log(result,"====");
// })

// MyPromise.resolve(10).then(value=> {
//     console.log(value)
// })
// MyPromise.resolve(p1()).then(value=> {
//     console.log(value)
// })

// p2().finally(value=> {
//     console.log('finally')
//     return p1();
// }).then(value=> {
//     console.log(value)
// },reason=> {
//     console.log(reason)
// })


// p1()
//     .then(value=> console.log(value))
//     .catch(reason=> console.log(reason))


// MyPromise.reject(10).then(value=> {
//     console.log(value)
// },reason=> {
//     console.log(reason)
// })
// MyPromise.reject(p1()).then(value=> {
//     console.log(value)
// },reason=> {
//     console.log(333)
//     console.log(reason)
// })


MyPromise.race([
    new MyPromise((resolve, reject) => { setTimeout(() => { resolve(100) }, 1000) }),
    undefined,
    new MyPromise((resolve, reject) => { setTimeout(() => { reject(100) }, 100) })
    ]).then((data) => {
        console.log('success ', data);
    }, (err) => {
        console.log('err ',err);
    });

MyPromise.race([
    new MyPromise((resolve, reject) => { setTimeout(() => { resolve(100) }, 1000) }),
    new MyPromise((resolve, reject) => { setTimeout(() => { resolve(200) }, 200) }),
    new MyPromise((resolve, reject) => { setTimeout(() => { reject(100) }, 100) })
]).then((data) => {
    console.log('success ', data);
}, (err) => {
    console.log('err ',err);
});
MyPromise.race([]).then((data) => {
    console.log('success ', data);
}, (err) => {
    console.log('err ',err);
});




